#!/usr/bin/python
# -*- coding: utf-8 -*-
import time
import random
import base64
import re

import web

urls = ("/auth/(.+)", "auth",
        "/list", "list",
        "/show/(.+)", "show",
        "/new", "new",
        "/add", "add",
        "/modify", "modify")
app = web.application(urls, globals())

db = web.database(dbn="sqlite", db="keys.sqlitedb")

def httpAuth():
    authinfo = web.ctx.env.get('HTTP_AUTHORIZATION')
    authreq = False
    if authinfo == None:
        authreq = True
    else:
        username,password = base64.decodestring(re.sub('^Basic ','',authinfo)).split(':')
        sysinfo = db.select('sysinfo')[0]
        if sysinfo.admin_passwd != password:
            authreq = True
    if authreq:
        web.header('WWW-Authenticate','Basic realm="Authenticate required"')
        web.ctx.status = '401 Unauthorized'
    return authreq
    
def normalize(key):
    if key.start_date == '' or key.start_date == None:
        key.start_date = 0
    if key.end_date == '' or key.end_date == None:
        key.end_date = 2**31-1
    if key.locked == '' or key.locked == None:
        key.locked = 0
    if key.comment == '' or key.comment == None:
        key.comment = ''
    return key

class Key(object):
    def __init__(self, dbkey=None):
        if dbkey:
            self.keyid = dbkey.keyid
            self.start_date = dbkey.start_date
            self.end_date = dbkey.end_date
            self.locked = dbkey.locked
            self.comment = dbkey.comment
        else:
            self.keyid = ''
            self.start_date = None
            self.end_date = None
            self.locked = None
            self.comment = None
        normalize(self)
        

def fmtDt(d):
    return time.strftime('%Y/%m/%d',time.localtime(d))

template_global = {'fmtDt': fmtDt,
                   'web': web,
                   }

class auth:
    def GET(self, keyid):
        keyid = keyid.replace("'", "''")
        now = int(time.time())
        keys = [Key(key) for key in db.select('keys', where="keyid='%s'" % keyid)]
        for key in keys:
            if key.locked == 0 and key.start_date <= now and now < key.end_date:
                return 'TRUE'
        else:
            return 'False'

class show:
    def GET(self, keyid):
        if httpAuth():
            return
        keyid = keyid.replace("'", "''")
        keys = [Key(key) for key in db.select('keys', where="keyid='%s'" % keyid)]
        if len(keys) > 0:
            show = web.template.frender('templates/show.template', globals=template_global)
            return show(keys[0], isnew=False)
        else:
            raise web.notfound()

class new:
    def GET(self):
        if httpAuth():
            return
        show = web.template.frender('templates/show.template', globals=template_global)
        return show(Key(), isnew=True)

class add:
    def POST(self):
        if httpAuth():
            return
        user_data = web.input(locked="0")
        random.seed(time.time())
        keyid = '%x' % random.randint(0x10000000, 0xffffffff)
        keys = [Key(key) for key in db.select('keys', where="keyid='%s'" % keyid)]
        while len(keys)>0:
            keyid = '%x' % random.randint(0x10000000, 0xffffffff)
            keys = [Key(key) for key in db.select('keys', where="keyid='%s'" % keyid)]
        start_date = int(time.mktime(time.strptime(user_data.start_date, '%Y/%m/%d')))
        end_date = int(time.mktime(time.strptime(user_data.end_date, '%Y/%m/%d')))
        locked = user_data.locked.replace("'", "''")
        comment = user_data.comment.replace("'", "''")
        
        key = Key()
        key.keyid = keyid
        key.start_date = start_date
        key.end_date = end_date
        key.locked = locked
        key.comment = comment
        db.insert('keys', keyid=keyid, start_date=start_date, end_date=end_date, locked=locked, comment=comment)
        
        result = web.template.frender('templates/result.template', globals=template_global)
        return result("Key %s added." % keyid, "show/%s" % keyid, "show %s" % keyid)

class modify:
    def POST(self):
        if httpAuth():
            return
        user_data = web.input(locked="0")
        action = user_data.action
        keyid = user_data.keyid
        keyid = keyid.replace("'", "''")
        if action == "Delete":
            db.delete('keys', where="keyid='%s'" % keyid)
            result = web.template.frender('templates/result.template', globals=template_global)
            return result("Key %s deleted." % keyid, "list", "return to list")
        else:
            start_date = int(time.mktime(time.strptime(user_data.start_date, '%Y/%m/%d')))
            end_date = int(time.mktime(time.strptime(user_data.end_date, '%Y/%m/%d')))
            locked = user_data.locked.replace("'", "''")
            comment = user_data.comment.replace("'", "''")
            
            db.update('keys', where="keyid='%s'" % keyid, start_date=start_date, end_date=end_date, locked=locked, comment=comment)
        
            result = web.template.frender('templates/result.template', globals=template_global)
            return result("Key %s modified." % keyid, "show/%s" % keyid, "show %s" % keyid)

class list:
    def GET(self):
        if httpAuth():
            return
        keys = [Key(key) for key in db.select('keys')]
        list = web.template.frender('templates/list.template', globals=template_global)
        return list(keys)

if __name__ == "__main__":
    web.wsgi.runwsgi = lambda func, addr=None: web.wsgi.runfcgi(func, addr)
    app.run()
